package cn.roadtrip.mtravelbusinessmodule.bs.basic;

import cn.roadtrip.mtravelbusinessmodule.dao.basic.BasicMapper;
import cn.roadtrip.mtravelbusinessmodule.dao.basic.vpo.SysCategoryItem;
import cn.roadtrip.mtravelbusinessmodule.dao.basic.vpo.SysTenantItem;
import cn.roadtrip.mtravelbusinessmodule.dao.bs.PortalProductMapper;
import cn.roadtrip.mtravelbusinessmodule.dao.bs.vpo.PortalProductItem;
import cn.roadtrip.mtravelbusinessmodule.sql.couple.tables.CoupleShop;
import cn.roadtrip.mtravelbusinessmodule.sql.couple.tables.CoupleShopPdt;
import cn.roadtrip.mtravelbusinessmodule.sql.couple.tables.SysTenant;
import cn.roadtrip.mtravelbusinessmodule.sql.couple.tables.records.CoupleShopPdtRecord;
import cn.roadtrip.mtravelbusinessmodule.sql.couple.travelline.dto.BsInsuranceDataDTO;
import cn.roadtrip.mtravelbusinessmodule.sql.dto.CoupleShopDTO;
import cn.roadtrip.mtravelbusinessmodule.sql.dto.CoupleShopPdtDTO;
import cn.roadtrip.umysqlmodule.transaction.TransactionRollback;
import cn.roadtrip.utilmodule.util.DataBean;
import lombok.*;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.jooq.DSLContext;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Date;

import static cn.roadtrip.mtravelbusinessmodule.sql.couple.tables.CoupleSchool.COUPLE_SCHOOL;
import static cn.roadtrip.mtravelbusinessmodule.sql.couple.tables.SysCategory.SYS_CATEGORY;
import static cn.roadtrip.mtravelbusinessmodule.sql.couple.travelline.tables.BsInsurancedata.BS_INSURANCEDATA;
import static cn.roadtrip.utilmodule.util.DataBean.err;
import static cn.roadtrip.utilmodule.util.DataBean.suc;

/**
 * 基础业务
 */
@Component
public class BasicBusinessImpl {

    @Autowired
    private SqlSessionFactory sqlSessionFactory;
    @Autowired
    private TransactionRollback transactionRollback;
    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private DSLContext dslContext;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    /**
     *
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @EqualsAndHashCode
    public static class Model_queryPortalProductList {
        private String cityName;//城市名,
        private String productCategory;//产品类别
        private Integer cpage;
        private Integer pagesize;
    }

    /**
     * 城市在字典中的前缀代码
     */
    public static final String SYS_DICT_CITY_PRECODE = "A02";

    /**
     * 店铺类型--景点
     */
    public static final String SYS_DICT_SHOP_TYPE_SCENIC = "1";

    /**
     * 查询门户商品列表
     *
     * @param model
     * @return
     */
    public DataBean queryPortalProductList(Model_queryPortalProductList model) {
        if (model.getProductCategory() == null || model.getProductCategory().trim().equals("")) {
            model.setProductCategory(null);
        }
        try (SqlSession sql = sqlSessionFactory.openSession(true)) {
            BasicMapper basicMapper = sql.getMapper(BasicMapper.class);

            //	1) 查询出字典中的城市以及对应得code
            java.util.List<SysCategoryItem> cityList = basicMapper.queryCityCodeList(SYS_DICT_CITY_PRECODE);
            if (cityList == null || cityList.isEmpty()) {
                return err("cityList-is-null", "没有找到当前城市");
            }
            SysCategoryItem currentCity = null;
            for (SysCategoryItem city : cityList) {
                if (city.getName().startsWith(model.getCityName())) {
                    currentCity = city;
                    break;
                }
            }
            if (currentCity == null) {
                return err("city-null", "没有找到当前城市");
            }

            //	2）查询出租户列表
            java.util.List<SysTenantItem> tenantItemList = basicMapper.queryAllTenantList();
            if (tenantItemList == null || tenantItemList.isEmpty()) {
                return err("tenantlist-is-null", "未注册任何租户信息");
            }
            //	3）从租户列表匹配出所在城市对应得租户
            Long tenantId = null;
            for (SysTenantItem tenantItem : tenantItemList) {
                String[] tids = tenantItem.getCityIds().split(",");
                for (String id : tids) {
                    if (id.equals(currentCity.getId() + "")) {
                        tenantId = tenantItem.getId();
                        break;
                    }
                }
                if (tenantId != null)
                    break;
            }
            if (tenantId == null) {
                return err("tenant-null", "当前城市没有对应的租户");
            }
            //	4）用筛选出来的租户ID去查询商品列表
            PortalProductMapper productMapper = sql.getMapper(PortalProductMapper.class);
            int count = productMapper.countPortalProductNum(tenantId, model.getProductCategory(), new Date(System.currentTimeMillis()));
            if (count == 0) {
                return DataBean.sucEmpty();
            }
            java.util.List<PortalProductItem> productItemList =
                    productMapper.queryPortalProductList(tenantId, model.getProductCategory(), new Date(System.currentTimeMillis()), model.getCpage(), model.getPagesize());
            return suc(productItemList, count, "suc", "操作成功");
        } catch (Exception e) {
            e.printStackTrace();
            return err("err", e.getMessage());
        }
    }


    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class Model_getShopProductView {
        private String prtId;
    }

    /**
     * 查询商品页面对象
     *
     * @param model
     * @return
     */
    public DataBean<CoupleShopPdtDTO> getShopProductView(Model_getShopProductView model) {
        CoupleShopPdtRecord coupleShopPdtRecord = dslContext.selectFrom(CoupleShopPdt.COUPLE_SHOP_PDT)
                .where(CoupleShopPdt.COUPLE_SHOP_PDT.ID.eq(model.getPrtId()))
                .fetchOne();
        if (coupleShopPdtRecord == null) {
            return DataBean.errEmpty();
        }
//        return DataBean.suc(coupleShopPdtRecord, 1, "suc", "操作成功");

        CoupleShopPdtDTO coupleShopPdtRecord2 = coupleShopPdtRecord.into(CoupleShopPdtDTO.class);
        return suc(coupleShopPdtRecord2, 1, "suc", "操作成功");
    }

    /**
     * 根据ID查询出产品列表
     *
     * @param ids
     * @return
     */
    public java.util.List<CoupleShopPdtRecord> _getShopProductListByIds(java.util.List<String> ids) {
        java.util.List<CoupleShopPdtRecord> coupleShopPdtRecord = dslContext.selectFrom(CoupleShopPdt.COUPLE_SHOP_PDT)
                .where(CoupleShopPdt.COUPLE_SHOP_PDT.ID.in(ids))
                .fetch();
        return coupleShopPdtRecord;
    }

    /**
     * 根据城市名查询出对应租户ID
     *
     * @param cityName
     * @return
     */

    public DataBean<String> _getTenantIdByCityName(String cityName) {

        //从字典查询出城市列表
        java.util.List<SysCategoryItem> cityList = dslContext.select(
                SYS_CATEGORY.ID,
                SYS_CATEGORY.NAME,
                SYS_CATEGORY.CODE
        ).from(
                SYS_CATEGORY
        ).where(
                SYS_CATEGORY.CODE.like(SYS_DICT_CITY_PRECODE + "%")
        ).fetch().into(SysCategoryItem.class);
        if (cityList.isEmpty()) {
            return err("cityList-is-null", "没有找到当前城市");
        }

        SysCategoryItem currentCity = null;
        for (SysCategoryItem city : cityList) {
            if (city.getName().startsWith(cityName)) {
                currentCity = city;
                break;
            }
        }
        if (currentCity == null) {
            return err("city-null", "没有找到当前城市");
        }

        //从字典查询出租户列表
        java.util.List<SysTenantItem> tenantItemList = dslContext.select(
                        SysTenant.SYS_TENANT.ID,
                        SysTenant.SYS_TENANT.NAME,
                        SysTenant.SYS_TENANT.CITY_IDS
                ).from(SysTenant.SYS_TENANT)
                .where(SysTenant.SYS_TENANT.STATUS.eq(1))
                .fetch().into(SysTenantItem.class);

        //	3）从租户列表匹配出所在城市对应得租户
        Long tenantId = null;
        for (SysTenantItem tenantItem : tenantItemList) {
            String[] tids = tenantItem.getCityIds().split(",");
            for (String id : tids) {
                if (id.equals(currentCity.getId() + "")) {
                    tenantId = tenantItem.getId();
                    break;
                }
            }
            if (tenantId != null)
                break;
        }
        if (tenantId == null) {
            return err("tenant-null", "当前城市没有对应的租户");
        }
        return suc(tenantId + "", 1, "suc", "操作成功");
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class Model_queryScenicByCity {
        private String cityName;//城市名称
    }

    /**
     * 查询出城市对应的景区
     *
     * @param model
     * @return
     */
    public DataBean queryScenicByCity(Model_queryScenicByCity model) {
        //从字典查询出城市列表
        java.util.List<SysCategoryItem> cityList = dslContext.select(
                SYS_CATEGORY.ID,
                SYS_CATEGORY.NAME,
                SYS_CATEGORY.CODE
        ).from(
                SYS_CATEGORY
        ).where(
                SYS_CATEGORY.CODE.like(SYS_DICT_CITY_PRECODE + "%")
        ).fetch().into(SysCategoryItem.class);
        if (cityList.isEmpty()) {
            return err("cityList-is-null", "没有找到当前城市");
        }

        SysCategoryItem currentCity = null;
        for (SysCategoryItem city : cityList) {
            if (city.getName().startsWith(model.getCityName())) {
                currentCity = city;
                break;
            }
        }
        if (currentCity == null) {
            return err("city-null", "没有找到当前城市");
        }

        //从字典查询出租户列表
        java.util.List<SysTenantItem> tenantItemList = dslContext.select(
                        SysTenant.SYS_TENANT.ID,
                        SysTenant.SYS_TENANT.NAME,
                        SysTenant.SYS_TENANT.CITY_IDS
                ).from(SysTenant.SYS_TENANT)
                .where(SysTenant.SYS_TENANT.STATUS.eq(1))
                .fetch().into(SysTenantItem.class);

        //	3）从租户列表匹配出所在城市对应得租户
        Long tenantId = null;
        for (SysTenantItem tenantItem : tenantItemList) {
            String[] tids = tenantItem.getCityIds().split(",");
            for (String id : tids) {
                if (id.equals(currentCity.getId() + "")) {
                    tenantId = tenantItem.getId();
                    break;
                }
            }
            if (tenantId != null)
                break;
        }
        if (tenantId == null) {
            return err("tenant-null", "当前城市没有对应的租户");
        }
        //从 couple-shop中查询出对应的景点
//        Result<CoupleShopRecord> shopList = dslContext.selectFrom(CoupleShop.COUPLE_SHOP)
//                .where(
//                        CoupleShop.COUPLE_SHOP.SHOP_TYPE.eq(SYS_DICT_SHOP_TYPE_SCENIC)
//                                .and(CoupleShop.COUPLE_SHOP.TENANT_ID.eq(tenantId + ""))
//                )
//                .orderBy(CoupleShop.COUPLE_SHOP.ID.desc())
//                .fetch();
        java.util.List<CoupleShopDTO> shopList = dslContext.selectFrom(CoupleShop.COUPLE_SHOP)
                .where(
                        CoupleShop.COUPLE_SHOP.SHOP_TYPE.eq(SYS_DICT_SHOP_TYPE_SCENIC)
                                .and(CoupleShop.COUPLE_SHOP.TENANT_ID.eq(tenantId + ""))
                )
                .orderBy(CoupleShop.COUPLE_SHOP.ID.desc())
                .fetch().into(CoupleShopDTO.class);
        if (shopList == null || shopList.isEmpty()) {
            return err("scenic-empty", "没有查询出景区");
        }
        return suc(shopList, shopList.size(), "suc", "操作成功");
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class VPO_getOpenCitylist {
        private String id;
        private String title;
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class Model_getOpenCitylist {
        private String parentId;//上级ID，省级传参0
    }

    /**
     * 获取开通得城市列表
     *
     * @param model
     * @return
     */
    public DataBean getOpenCitylist(
            Model_getOpenCitylist model
    ) {
        if (model.getParentId() == null || model.getParentId().trim().equals("0")) {
            model.setParentId("1230769196661510146");//查询省级
        }
        try {
            return dslContext.transactionResult(ctx -> {

                java.util.List<VPO_getOpenCitylist> list = dslContext.select(
                        SYS_CATEGORY.ID.as("id"),
                        SYS_CATEGORY.NAME.as("title")
                ).from(
                        SYS_CATEGORY
                ).where(
                        SYS_CATEGORY.PID.eq(model.getParentId())
                ).fetchInto(VPO_getOpenCitylist.class);
                if (list == null || list.isEmpty()) {
                    return DataBean.sucEmpty();
                }


                dslContext.commit();
                return suc(list, list.size(), "suc", "操作成功");
            });
        } catch (Exception e) {
            e.printStackTrace();
            return err("trans-err", e.getMessage());
        }
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class VPO_getSchoolList {
        private String schoolId;
        private String title;
        private String address;
        private String cityId;
    }

    /**
     * 查询所有开通得学校，由前端过滤筛选
     *
     * @return
     */
    public DataBean getSchoolList(
    ) {
        try {
            return dslContext.transactionResult(ctx -> {
                //todo
                java.util.List<VPO_getSchoolList> list = dslContext.select(
                        COUPLE_SCHOOL.ID.as("id"),
                        COUPLE_SCHOOL.TITLE.as("title"),
                        COUPLE_SCHOOL.ADDRESS.as("address"),
                        COUPLE_SCHOOL.CITY_ID.as("cityId")
                ).from(
                        COUPLE_SCHOOL
                ).fetchInto(VPO_getSchoolList.class);

                dslContext.commit();
                return suc(true, 1, "suc", "操作成功");
            });
        } catch (Exception e) {
            e.printStackTrace();
            return err("trans-err", e.getMessage());
        }
    }


    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class VPO_getFrontStaticPageContent {
        private String key;
        private String type;
        private String content;
    }

    /**
     * 查询出前端静态内容文本
     *
     * @return
     */
    public DataBean getFrontStaticPageContent(
    ) {
        try {
            return dslContext.transactionResult(ctx -> {
                //todo
                java.util.List<VPO_getFrontStaticPageContent> list = dslContext.resultQuery("SELECT\n" +
                        "sys_category.`code` as `key`,\n" +
                        "sys_category.`name` as type,\n" +
                        "content.msg as `content`\n" +
                        "FROM(\n" +
                        "SELECT\n" +
                        "sys_category.id\n" +
                        "FROM\n" +
                        "sys_category\n" +
                        "WHERE\n" +
                        "sys_category.`code` like 'B01-1A%'\n" +
                        ") as t\n" +
                        "LEFT JOIN sys_category\n" +
                        "ON sys_category.id = t.id\n" +
                        "LEFT JOIN content\n" +
                        "ON content.type_id = t.id").fetchInto(VPO_getFrontStaticPageContent.class);

                dslContext.commit();
                return suc(list, list.size(), "suc", "操作成功");
            });
        } catch (Exception e) {
            e.printStackTrace();
            return err("trans-err", e.getMessage());
        }
    }


    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class Model_getInsuranceTypeList {
        private Integer playDays;//游玩天数
    }

    /**
     * 查询保险类型列表
     *
     * @param model
     * @return
     */
    public DataBean getInsuranceTypeList(
            Model_getInsuranceTypeList model
    ) {
        try {
            return dslContext.transactionResult(ctx -> {
                //todo
                java.util.List<BsInsuranceDataDTO> list = dslContext.selectFrom(
                        BS_INSURANCEDATA
                ).where(
                        BS_INSURANCEDATA.TRASH.eq(false)
                ).and(
                        BS_INSURANCEDATA.MINDAY.le(model.getPlayDays())
                ).and(
                        BS_INSURANCEDATA.MAXDAY.ge(model.getPlayDays())
                ).fetchInto(BsInsuranceDataDTO.class);
                dslContext.commit();
                if (list == null || list.isEmpty()) {
                    return DataBean.sucEmpty();
                }
                list.forEach(o -> {
                    o.setThirdCode("");
                    o.setThirdPrice(new BigDecimal(0));
                });
                return suc(list, list.size(), "suc", "操作成功");
            });
        } catch (Exception e) {
            e.printStackTrace();
            return err("trans-err", e.getMessage());
        }
    }


    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class Model_getPickupZoneArea {
        private String cityId;
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class VPO_getPickupZoneArea {
        private String id;
        private String title;
        private Integer freePeoplenum;
        private String cityId;
        private String lat_log;
    }

    /**
     * 获取接送上车围栏
     *
     * @param model
     * @return
     */
    public DataBean getPickupZoneArea(
            Model_getPickupZoneArea model
    ) {
        try {
            return dslContext.transactionResult(ctx -> {
                //todo
                java.util.List<VPO_getPickupZoneArea> list = dslContext.resultQuery(
                        "SELECT\n" +
                                "couple_activity_map_draw_acircle.id,\n" +
                                "couple_activity_map_draw_acircle.title,\n" +
                                "couple_activity_map_draw_acircle.astrict_person_num as freePeoplenum,\n" +
                                "couple_activity_map_draw_acircle.city_id as cityId,\n" +
                                "couple_activity_map_draw_acircle.circle_lat_log as lat_log\n" +
                                "FROM\n" +
                                "couple_activity_map_draw_acircle\n" +
                                "WHERE\n" +
                                "couple_activity_map_draw_acircle.city_id = ?",
                        model.getCityId()
                ).fetchInto(VPO_getPickupZoneArea.class);
                dslContext.commit();
                return suc(list, list.size(), "suc", "操作成功");
            });
        } catch (Exception e) {
            e.printStackTrace();
            return err("trans-err", e.getMessage());
        }
    }


    /**
     * 获取所有城市围栏
     *
     * @return
     */
    public DataBean getAllCityZoneArea(
    ) {
        try {
            return dslContext.transactionResult(ctx -> {
                //todo
                java.util.List<VPO_getPickupZoneArea> list = dslContext.resultQuery(
                        "SELECT\n" +
                                "couple_activity_map_draw_acircle.id,\n" +
                                "couple_activity_map_draw_acircle.title,\n" +
                                "couple_activity_map_draw_acircle.astrict_person_num as freePeoplenum,\n" +
                                "couple_activity_map_draw_acircle.city_id as cityId,\n" +
                                "couple_activity_map_draw_acircle.circle_lat_log as lat_log\n" +
                                "FROM\n" +
                                "couple_activity_map_draw_acircle\n"
                ).fetchInto(VPO_getPickupZoneArea.class);
                dslContext.commit();
                return suc(list, list.size(), "suc", "操作成功");
            });
        } catch (Exception e) {
            e.printStackTrace();
            return err("trans-err", e.getMessage());
        }
    }
}
